<script setup>
import { getAllMachine } from "@/api/pannel/machinePannel.js";
import MqttServer from "@/socket/mqtt";
import { computed, onMounted, onUnmounted } from "vue";

let mqttServer = null;
const socket = inject("socket");
const machineList = ref([]);
const machineItemWidth = ref(0);
const groupSize = ref(24);
const props = defineProps({
  columns: {
    type: [String, Number],
    default: 10,
  },
  rows: {
    type: [String, Number],
    default: 0,
  },
  gap: {
    type: [String, Number],
    default: 10,
  },
  params: {
    type: Object,
    default: () => ({}),
  },
});

/**
 * @description: 动态样式
 */
const dynamicStyle = computed(() => {
  const style = {};

  style["grid-template-columns"] = `repeat(auto-fill, minmax(220px, 1fr))`;

  if (Number(props.rows) > 0) {
    style["grid-template-rows"] = `repeat(${Number(props.rows)}, 1fr)`;
  }

  style["grid-gap"] = `${Number(props.gap)}px`;
  return style;
});

const groupedMachines = computed(() => {
  const groups = [];

  for (let i = 0; i < machineList.value.length; i += groupSize.value) {
    groups.push(machineList.value.slice(i, i + groupSize.value));
  }

  return groups;
});

const loadData = async () => {
  const { machines } = await getAllMachine({ ...props.params, key: "topic" });
  const topics = [];
  machineList.value = machines.map((item) => {
    item.type =
      item.zt === "未开工"
        ? "red"
        : item.gxmc.includes("调机")
        ? "blur"
        : "green";
    if (item.topic) {
      item.sj = 0;
      item.oldValue = 0;
      item.showTipicIcon = false;
      item.runTime = 0;
      topics.push(item.topic);
    }
    return item;
  });

  if (mqttServer === null) {
    mqttServer = new MqttServer([topics]);
    console.log(mqttServer);
  }

  // 定义消息处理函数
  const handleMessage = (message) => {
    const data = {
      mete: message,
      topic: message.destinationName,
      data: {},
      metaData: {},
    };

    if (message.topic && message.topic.startsWith("Dev/")) {
      data.data = JSON.parse(message.payloadString);
    } else if (message.topic && message.topic.startsWith("RJ")) {
      const payload = JSON.parse(message.payloadString);
      const sj = payload.Data.value;
      data.data = { sj };
      data.metaData = payload;
    } else if (message.topic && message.topic.startsWith("XH")) {
      const payload = JSON.parse(message.payloadString);
      const sj = payload.Data.value;
      data.data = { sj };
      data.metaData = payload;
      console.log("other message:", message);
    } else if (message.topic && message.topic.startsWith("HD")) {
      const payload = JSON.parse(message.payloadString);
      const sj = payload.Data.value;
      data.data = { sj };
      data.metaData = payload;
      console.log("other message:", message);
    }

    toUpdateItem(data);
  };

  // 注册消息回调
  mqttServer.addMessageCallback(handleMessage);

  // 在组件卸载时移除回调
  onUnmounted(() => {
    socket.removeAllListeners("report-system-update");
    if (mqttServer) {
      mqttServer.removeMessageCallback(handleMessage);
    }
  });
};

function convertMillisecondsToHMS(milliseconds) {
  const hours = Math.floor(milliseconds / (1000 * 60 * 60));
  const minutes = Math.floor((milliseconds % (1000 * 60 * 60)) / (1000 * 60));
  const seconds = Math.floor((milliseconds % (1000 * 60)) / 1000);

  return `${hours}:${String(minutes).padStart(2, "0")}:${String(
    seconds
  ).padStart(2, "0")}`;
}

const toUpdateItem = (message) => {
  let machine;
  let sj;
  if (message.topic.startsWith("Dev/")) {
    sj = Number(message.data.sj);
    machine = machineList.value.filter((item) => item.topic === message.topic);
  } else if (message.topic.startsWith("RJ")) {
    const {
      metaData: { Data },
    } = message;

    if (Data.upload_name === "产量") {
      sj = Number(message.data.sj);
      machine = machineList.value.filter(
        (item) =>
          item.topic === message.topic && item.topicName == Data.device_name
      );
    }

    if (Data.upload_name === "运行时间") {
      machine = machineList.value.filter(
        (item) =>
          item.topic === message.topic && item.topicName == Data.device_name
      );

      machine.map((item) => {
        item.runTime = convertMillisecondsToHMS(Data.value * 1000);
      });
      return;
    }
  } else if (message.topic.startsWith("XH")) {
    const {
      metaData: { Data },
    } = message;

    if (Data.upload_name === "产量") {
      sj = Number(message.data.sj);
      machine = machineList.value.filter(
        (item) =>
          item.topic === message.topic && item.topicName == Data.device_name
      );
    }

    if (Data.upload_name === "运行时间") {
      machine = machineList.value.filter(
        (item) =>
          item.topic === message.topic && item.topicName == Data.device_name
      );

      machine.map((item) => {
        item.runTime = convertMillisecondsToHMS(Data.value * 1000);
      });
      return;
    }
  } else if (message.topic.startsWith("HD")) {
    const {
      metaData: { Data },
    } = message;

    if (Data.upload_name.includes("产量")) {
      sj = Number(message.data.sj);
      machine = machineList.value.filter(
        (item) =>
          item.topic === message.topic && item.topicName == Data.device_name
      );
    }

    if (Data.upload_name.includes("运行时间")) {
      machine = machineList.value.filter(
        (item) =>
          item.topic === message.topic && item.topicName == Data.device_name
      );

      machine.map((item) => {
        item.runTime = convertMillisecondsToHMS(Data.value * 1000);
      });
      return;
    }
  }
  if (machine) {
    machine.map((item) => {
      item.oldValue = item.sj;
      item.sj = sj;
      item.showTipicIcon = true;
      setTimeout(() => {
        item.showTipicIcon = false;
      }, 800);
    });
  }
};

const getMachineItemWidth = (retryCount = 0) => {
  const dom = document.querySelector(".ps-machine-item");
  if (dom) {
    console.log(dom.offsetWidth);
    return dom.offsetWidth;
  } else if (retryCount < 10) {
    // 设置最大重试次数
    setTimeout(() => {
      getMachineItemWidth(retryCount + 1);
    }, 100); // 延迟100ms后重试
  } else {
    console.error("无法获取 .ps-machine-item 的宽度");
    return null;
  }
};

defineExpose({ loadData });

onMounted(() => {
  const width = getMachineItemWidth();
  machineItemWidth.value = width;
});

onMounted(loadData);
</script>

<template>
  <div style="height: 100%">
    <el-carousel direction="vertical" :interval="1000 * 10">
      <el-carousel-item v-for="(group, index) in groupedMachines" :key="index">
        <div class="ps-machine" :style="dynamicStyle">
          <div v-for="machine in group" :key="machine.jtbh">
            <div class="ps-machine-item" :class="[machine.type]">
              <div
                class="machineID"
                :style="{
                  'background-color': `var(--cbs-machine-${machine.type})`,
                }"
              >
                <span>{{ machine.zt }}</span>
              </div>

              <div class="machineName">
                <span>{{ machine.jtmc }}</span>
                <template v-if="machine.topic && machine.showTipicIcon">
                  <el-icon
                    name="Sort"
                    size="16"
                    style="color: var(--cbs-machine-green)"
                    ><Sort
                  /></el-icon>
                </template>
              </div>

              <div class="desc-item">
                <span class="label">设备编号</span>
                <span>{{ machine.jtbh }}</span>
              </div>

              <div class="desc-item" v-if="machine.gxmc">
                <span class="label">在制工序</span>
                <span>{{ machine.gxmc }}</span>
              </div>

              <div class="desc-item" v-if="machine.gdno">
                <span class="label">在制工单</span>
                <span>{{ machine.gdno }}</span>
              </div>

              <div
                class="desc-item"
                v-if="machine.topic && machine.type !== 'red'"
              >
                <span class="label">采数数据</span>
                <span v-if="machine.oldValue === 0 && machine.sj === 0"
                  >等待上报...</span
                >

                <template v-else>
                  <AnimatedNumber
                    style="display: inline-block"
                    :from="machine.oldValue"
                    :to="machine.sj"
                    :key="`${machine.jtbh},${machine.jtmc}`"
                    :duration="1000"
                  />
                </template>
              </div>

              <div class="desc-item" v-if="machine.topic && machine.topicName">
                <span class="label">运行时间</span>
                <span>{{ machine.runTime }}</span>
              </div>

              <div class="sfm" v-else>{{ machine.sfm }}</div>
            </div>
          </div>
        </div>
      </el-carousel-item>
    </el-carousel>
  </div>
</template>

<style scoped lang="scss">
.ps-machine {
  display: grid;
  font-size: 14px;
  &-item {
    min-height: 135px;
    border-radius: 10px;
    padding: 26px 10px 0;
    border-width: 2px;
    border-style: solid;
    position: relative;
    overflow: hidden;
    color: #fff;
    // background-color: #fff;

    // 设备ID
    .machineID {
      position: absolute;
      top: 0;
      left: 0;
      color: #fff;
      padding: 4px 8px;
      border-bottom-right-radius: 10px;
    }

    .machineName {
      text-wrap: nowrap;
      font-size: 18px;
      font-weight: bold;
      text-align: center;
      vertical-align: middle;
      margin-bottom: 5px;
      transition: all 0.5s;
      position: absolute;
      top: 0;
      left: 50%;
      transform: translateX(-50%);
    }

    .sfm {
      position: absolute;
      bottom: 0;
      left: 50%;
      transform: translateX(-50%);
    }

    .desc-item {
      line-height: 20px;

      .label {
        display: inline-block;
        // color: #909399;
        width: 4.5em;
      }
    }

    &.red {
      border-color: var(--cbs-machine-red);
    }

    &.blue {
      border-color: var(--cbs-machine-blue);
    }

    &.green {
      border-color: var(--cbs-machine-green);
    }
  }
}

:deep(.el-carousel) {
  height: 100%;
  .el-carousel__container {
    height: 100%;
  }
}
</style>
